package org.ala.tcp_feign_client.spring.feign.clients;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import org.ala.tcp_feign_client.ITcpFeignClient;
import org.ala.tcp_feign_client.context.TcpFeignClientContext;
import org.ala.tcp_feign_client.spring.feign.TcpFeign.LoginSuccessConsumer;
import org.ala.tcp_feign_common.logs.LoggerFactory;
import org.ala.tcp_feign_common.msg.biz_resp.BizRespByteMessage;
import org.slf4j.Logger;


/**
 * 默认的TcpFeignClientHolder
 *
 * @author 骆毅(ala)
 * @date 2024年4月22日
 */
public abstract class AbstractTcpFeignClientHolder implements ITcpFeignClientHolder {

	
	static Logger log = LoggerFactory.getLogger("tcp-feign", "client");
	
	
	/**
	 * 当前持有的全部链接
	 */
	protected ArrayList<ITcpFeignClient> clients;
	/**
	 * 链接后缀
	 */
	protected String suffix;
	/**
	 * resp消息回调
	 */
	protected Consumer<BizRespByteMessage> respCallback;
	
	
	public AbstractTcpFeignClientHolder(String suffix, Consumer<BizRespByteMessage> respCallback) {
		super();
		this.suffix = suffix;
		this.respCallback = respCallback;
	}

	@Override
	public List<ITcpFeignClient> all() {
		return clients;
	}

	@Override
	public void initClients(String hosts) {
		String[] remoteHosts = allHosts(hosts);
		clients = new ArrayList<>(remoteHosts.length);
		
		//	初始化链接
		for (String hostStr : remoteHosts) {
			appendClient(hostStr);
		}
	}
	/**
	 * 追加client
	 * @param	hostStr: ${host}:${port}:${username}:${password}
	 */
	protected void appendClient(String hostStr) {
		ITcpFeignClient client = createClient(hostStr);
		
		//	拿到其索引
		int i = clients.size();
		clients.add(client);
		client.bindLoginCallback((c) -> new LoginSuccessConsumer(i, clients));
	}
	/**
	 * host字符串创建ITcpFeignClient
	 */
	protected ITcpFeignClient createClient(String hostStr) {
		String[] ss = hostStr.split(":");
		String host = ss[0];
		int port = Integer.parseInt(ss[1]);
		String username = ss[2];
		String password = ss[3];
		
		//	通过context管理链接
		//	这里只创建链接对象，并不真的建立链接。真实链接在第一次使用时建立
		ITcpFeignClient client = TcpFeignClientContext.instance().getOrCreateClient(host, port, suffix, username, password, null);
		client.bindBizRespCallback((resp) -> {
			respCallback.accept(resp);
		});
		return client;
	}

	
	/**
	 * 取所有的服务器地址
	 * <p>	格式：${host}:${port}:${username}:${password}
	 */
	protected abstract String[] allHosts(String hosts);
	
	
}
